package com.cainli.image;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.DisplayMetrics;
import android.view.Gravity;

public class GifDrawable extends Drawable implements GifImage.Callback {
	
	private boolean mApplyGravity;

	private GifState mGifState;

	private int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;

	private int mGifWidth;
	private int mGifHeight;

	public GifDrawable(File f, Resources res) throws IOException {
		this(new GifImage(f, URLDrawable.sDefaultDrawableParms.mTaskType), res);
	}

	public GifDrawable(GifImage image) {
		this(image, null);
	}

	public GifDrawable(GifImage image, Resources res) {
		this(new GifState(image), res);
		this.mGifState.mTargetDensity = this.mTargetDensity;
	}

	public GifDrawable(GifState gifState, Resources res) {
		this.mGifState = gifState;
		gifState.mGif.addCallBack(this);
		if (res != null) {
			this.mTargetDensity = res.getDisplayMetrics().densityDpi;
		} else {
			this.mTargetDensity = gifState.mTargetDensity;
		}
		this.computeImageSize();
	}

	/**
	 * Get the gravity used to position/stretch the bitmap within its bounds.
	 * See android.view.Gravity
	 * 
	 * @return the gravity applied to the bitmap
	 */
	public int getGravity() {
		return mGifState.mGravity;
	}

	/**
	 * Set the gravity used to position/stretch the bitmap within its bounds.
	 * See android.view.Gravity
	 * 
	 * @param gravity
	 *            the gravity
	 */
	public void setGravity(int gravity) {
		mGifState.mGravity = gravity;
		mApplyGravity = true;
	}

	@Override
	protected void onBoundsChange(Rect bounds) {
		super.onBoundsChange(bounds);
		mApplyGravity = true;
	}

	private final Rect mDstRect = new Rect();

	@Override
	public void draw(Canvas canvas) {
		// long now = android.os.SystemClock.uptimeMillis();
		// if (startTime == 0) { // first time
		// startTime = now;
		// }

		// 计算坐标
		if (mApplyGravity) {
			Gravity.apply(mGifState.mGravity, mGifWidth, mGifHeight,
					getBounds(), mDstRect);
			mApplyGravity = false;
		}
		// 画当前帧
		mGifState.mGif.draw(canvas, mDstRect, mGifState.mPaint);

		// if(task == null || task.end)
		// {
		// task = new DecodeNextFrameTask(image, image.getDelay());
		// task.execute();
		// }

		// int dur = getDuration();
		// if (dur == 0) {
		// dur = 1000;
		// }
		// int relTime = (int)((now - startTime) % dur);
		// movie.setTime(relTime);
		// movie.draw(canvas, mDstRect.left, mDstRect.top);
		// invalidateSelf();
	}

	public GifImage getImage() {
		return mGifState.mGif;
	}

	/**
	 * 计算图片
	 */
	private void computeImageSize() {
		mGifWidth = mGifState.mGif.getScaledWidth(mTargetDensity);
		mGifHeight = mGifState.mGif.getScaledHeight(mTargetDensity);
	}

	@Override
	public int getIntrinsicWidth() {
		return mGifWidth;
	}

	@Override
	public int getIntrinsicHeight() {
		return mGifHeight;
	}

	@Override
	public int getOpacity() {
		return PixelFormat.TRANSPARENT;
	}

	@Override
	public void setAlpha(int alpha) {
		mGifState.mPaint.setAlpha(alpha);
	}

	@Override
	public void setColorFilter(ColorFilter cf) {
		mGifState.mPaint.setColorFilter(cf);
	}

	@Override
	public void setFilterBitmap(boolean filter) {
		mGifState.mPaint.setFilterBitmap(filter);
	}

	@Override
	public void setDither(boolean dither) {
		mGifState.mPaint.setDither(dither);
	}

	/**
	 * 设置density
	 * 
	 * @param mTargetDensity
	 */
	public void setTargetDensity(int density) {
		if (density != this.mTargetDensity) {
			this.mTargetDensity = density == 0 ? DisplayMetrics.DENSITY_DEFAULT
					: density;
			computeImageSize();
			invalidateSelf();
		}
	}

	public static boolean isGifFile(File f) throws IOException {
		RandomAccessFile rf = new RandomAccessFile(f, "r");
		// 先读6个字节
		byte[] tmp = new byte[10];
		rf.read(tmp);
		// 不是gif文件
		if (tmp[0] != (byte) 'G' || tmp[1] != (byte) 'I'
				|| tmp[2] != (byte) 'F') {
			rf.close();
			return false;
		} else {
			rf.close();
			return true;
		}
	}

	@Override
	public void invalidateSelf() {
		super.invalidateSelf();
	}

	@Override
	protected void finalize() throws Throwable {
		super.finalize();
		mGifState.mGif.removeCallBack(this);
	}

	@Override
	public ConstantState getConstantState() {
		return mGifState;
	}

	/**
	 * 用来做缓存的
	 * 
	 * 
	 */
	final static class GifState extends ConstantState {
		GifImage mGif;
		int mChangingConfigurations;
		int mGravity = Gravity.FILL;
		int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
		Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG);

		public GifState(GifImage gif) {
			this.mGif = gif;
		}

		@Override
		public int getChangingConfigurations() {
			return mChangingConfigurations;
		}

		@Override
		public Drawable newDrawable() {
			return new GifDrawable(this, null);
		}

		@Override
		public Drawable newDrawable(Resources res) {
			return new GifDrawable(this, res);
		}

	}

	// private static void skipImage(RandomAccessFile rf) throws IOException
	// {
	// // 跳过9个字节
	// rf.skipBytes(9);
	// int packed = rf.read();
	//
	// boolean lctFlag = (packed & 0x80) != 0; // 1 - local color table flag
	// int lctSize = 2 << (packed & 7); // 6-8 - local color table size
	// if(lctFlag)
	// {
	// rf.skipBytes(lctSize*3);
	// }
	//
	// }
	//
	// private static void skip(RandomAccessFile rf) throws IOException
	// {
	// int blockSize = rf.read();
	// if(blockSize > 0)
	// {
	// rf.skipBytes(blockSize);
	// }
	// }
}
